package ServidorDistribuido;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.PatternSyntaxException;

public class HiloEscuchaCliente implements Runnable{
    InetAddress ipCliente;
    Socket socketCliente;
    static String servidoresDisponibles = null;
    static String archivosPorServidor = null;

    public HiloEscuchaCliente(InetAddress ipCliente, Socket socketCliente) {
        this.ipCliente = ipCliente;
        this.socketCliente = socketCliente;
    }

    public static ArrayList removeDuplicatesArrayList(ArrayList items) {
        Set set = new LinkedHashSet();
        set.addAll(items);
        return new ArrayList(set);
    }

    public String buscarServidoresDisponibles(){
        String tresServidores = "";
        Set <InetAddress> set = Servidor.estadoEjecucion.keySet();
        InetAddress siguienteIp = null;
        Iterator <InetAddress> itr = set.iterator();
        int cont = 0;
        while (itr.hasNext() && cont <= 2) {
          siguienteIp = itr.next();
          if (!Servidor.estadoEjecucion.get(siguienteIp)){
            cont++;
            try{
                if (siguienteIp.equals(Servidor.ipServidorCoord)){
                    continue;
                }
                tresServidores += siguienteIp.toString().split("[/]")[1] + "|";
            }catch (Exception ee){
                tresServidores = "Error";
            }
            System.out.println("HEC: Se añadio a la lista de servidores disponibles "
                + siguienteIp + ":" + Servidor.estadoEjecucion.get(siguienteIp));
          }
        }
        tresServidores = tresServidores.substring(0, tresServidores.length()-1);
        System.out.println("HEC: tresServidores ejecucion: " + tresServidores);
        return tresServidores;//los tres primeros de todos los que esten disponibles
    }

    public String buscarArchivosPorServidor(String archivo){
        String tresServidores = "";
        int version = Servidor.versionArchivo.get(archivo);
        String parArchivoVersion = archivo + "|" + version;
        ArrayList <InetAddress> servidoresConArchivo = new ArrayList <InetAddress> ();
        servidoresConArchivo = Servidor.archivosPorServidor.get(parArchivoVersion);
        servidoresConArchivo = removeDuplicatesArrayList(servidoresConArchivo);
        System.out.println("buscarArchivosPorServidor: " + servidoresConArchivo);
        try{
            Iterator <InetAddress> itr = servidoresConArchivo.iterator();
            int cont = 0;
            InetAddress siguienteIp = null;
            while (itr.hasNext() && cont <= 2) {
                siguienteIp = itr.next();
                tresServidores = siguienteIp.toString().split("[/]")[1] + "|";
                System.out.println("HEC: tresServidores busqueda: " + tresServidores);
            }
        }catch (IndexOutOfBoundsException e){
            tresServidores = "No hay suficientes servidores que mantengan una copia del archivo";
        }
        if(tresServidores.equals("")){
            tresServidores = "nohay";
        }
        tresServidores = tresServidores.substring(0, tresServidores.length()-1);
        return tresServidores;
    }

    public void run() {
        System.out.println("HEC: Comenzo el hilo de escucha para el cliente.");
        BufferedReader in = null;
        PrintWriter out = null;
//        ObjectInputStream ois = null;
//        ObjectOutputStream oos = null;
        String leido = null;
        String [] parseLeido = null;
        try {
            in = new BufferedReader(new InputStreamReader(socketCliente.getInputStream()));
            out = new PrintWriter(socketCliente.getOutputStream(),true);

            while (Servidor.esCoordinador && (leido = in.readLine()) != null) {
                try {
                    parseLeido = leido.split("[|]");
                } catch (PatternSyntaxException e) {
                    parseLeido[0] = leido;
                }
                if (parseLeido[0].equals("Ejecucion")) {
                    System.out.println("HEC: Cliente solicito Ejecucion");
                    servidoresDisponibles = buscarServidoresDisponibles();
                    out.println(servidoresDisponibles);
                    out.flush();
                } else if (parseLeido[0].equals("Busqueda")) {
                    System.out.println("HEC: Cliente solicito Busqueda");
                    String archivo = parseLeido[1];
                    archivosPorServidor = buscarArchivosPorServidor(archivo);
                    out.println(archivosPorServidor);
                    out.flush();
                }
                System.out.println("HEC: El cliente envio: " + leido);
            }
        } catch (IOException ex) {
            Logger.getLogger(HiloEscuchaCliente.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
